/**
 * ES 数据管理
 */

#ifndef COMMON_DATA_ES_H
#define COMMON_DATA_ES_H

#include <memory>
#include <string>
#include <vector>

#include "elastic.h"
#include "user.hxx"
#include "message.hxx"

namespace chat {
/**
 * @brief 工厂类：构建一个es客户端对象
 */
class ESClientFactory {
   public:
    static std::shared_ptr<elasticlient::Client> create(
        const std::vector<std::string> host_list);
};

/**
 * @brief ES数据库存储用户的元数据(uid, phone, nickname, description, avatar_id)
 * - 用于 用户的搜索
 *
 */
class ESUser {
   public:
    ESUser(const std::shared_ptr<elasticlient::Client> &client)
        : client_(client) {}

    /**
     * @brief 向 ES 中创建User索引
     */
    bool createIndex();

    /**
     * @brief 向User索引中添加或修改数据
     */
    bool appendData(const std::string &uid, const std::string &phone,
                    const std::string &nickname, const std::string &description,
                    const std::string &avatar_id);

    /**
     * @brief 向User索引中搜索满足条件的 user
     * @param key[in]: 关键字, 用于进行用户匹配
     * @param ids[in]: 过滤条件，如果uid存在于ids, 那么就过滤掉
     *
     * @note 该函数实际用于添加好友对用户的搜索,
     * ids中存放的就是自己的uid和好友的uid，自然不应该被搜索出来
     */
    std::vector<User> search(const std::string &key,
                             const std::vector<std::string> &ids);

   private:
    std::shared_ptr<elasticlient::Client> client_ = nullptr;
};

using ESUserPtr = std::shared_ptr<ESUser>;

class ESMessage {
   public:
    ESMessage(const std::shared_ptr<elasticlient::Client> &client)
        : client_(client) {}

    /**
     * @brief 向 ES 中创建Message索引
     */
    bool createIndex();

    /**
     * @brief 向Message索引中添加或修改数据
     */
    bool appendData(const std::string &chat_session_id,
                    const std::string &message_id,
                    const boost::posix_time::ptime &create_time,
                    const std::string &message_content,
                    const std::string &user_id);

    /**
     * @brief 向Message索引中搜索满足条件的 message
     * @param key[in]: 关键字, 用于进行文本信息匹配
     * @param chat_session_id[in]: 过滤条件，用于指定搜索的会话
     *
     * @note 该函数实际用于在指定会话中搜索包含关键字的消息
     */
    std::vector<Message> search(const std::string &key,
                                const std::string &chat_session_id);
    
    /**
     * @brief 从Message索引中删除指定会话的所有消息
     * @param message_id[in]: 消息id
     */
    bool remove(const std::string &message_id);
    

   private:
    std::shared_ptr<elasticlient::Client> client_ = nullptr;
};
using ESMessagePtr = std::shared_ptr<ESMessage>;

}  // namespace chat

#endif  // COMMON_DATA_ES_H